package com.keqiang.chart.impl.pie.impl.pseudo3d

import android.graphics.Canvas
import com.keqiang.chart.base.BaseChartView
import com.keqiang.chart.impl.pie.Base3DTouchHandler
import com.keqiang.chart.impl.pie.BasePieChart3D
import com.keqiang.chart.impl.pie.impl.normal.PieEntity
import com.keqiang.chart.impl.pie.render.BaseDataRender
import com.keqiang.chart.impl.pie.render.BaseLabelRender
import com.keqiang.chart.utils.toRadian
import kotlin.math.sin

/**
 * 3D饼状图
 *
 * @author Created by wanggaowan on 2022/8/2 15:14
 */
open class PieChart3D(view: BaseChartView<*>) : BasePieChart3D<List<PieEntity>>(view) {

    override var touchHandler: Base3DTouchHandler<PieChart3D, PieEntity>? =
        PieChart3DTouchHandler(this)

    override var labelRender: BaseLabelRender<PieChart3D>? = PieChart3DLabelRender(this)

    var highLightRender: HighLightRender? = PieChart3DHighLightRender(this)

    override fun isEmptyData(): Boolean {
        return data.isNullOrEmpty()
    }

    override fun getCenter(): Pair<Float, Float> {
        val pair = super.getCenter()
        return pair.copy(pair.first, pair.second - height / 2f)
    }

    override val dataRender: BaseDataRender<PieChart3D> = PieChart3DDataRender(this)

    /**
     * 获取实际绘制时的翻转角度
     */
    fun getDrawFlipAngle(): Float {
        return flipAngle + (touchHandler?.flipAngle ?: 0f)
    }

    /**
     * 获取实际绘制时的高度
     */
    fun getDrawHeight(): Float {
        return height * sin(getDrawFlipAngle().toRadian)
    }
}

/**
 * 高亮数据绘制器
 *
 * @author Created by wanggaowan on 2022/11/1 09:55
 */
abstract class HighLightRender(val chart: PieChart3D) {
    /**
     * 绘制高亮数据，此方法会被调用多次
     *
     * @param drawBottom 是否是绘制底部扇形
     * @param drawTop 是否是绘制顶部扇形
     * @param drawShadowTop 是否是绘制上半部分(180°~360°范围)顶部和底部扇形之间的阴影
     * @param drawShadowBottom 是否是绘制下半部分(0°~180°范围)顶部和底部扇形之间的阴影
     */
    abstract fun onDraw3D(canvas: Canvas, drawStartAngle: Float, drawSweepAngle: Float, data: PieEntity,
                          drawTop: Boolean, drawBottom: Boolean, drawShadowTop: Boolean, drawShadowBottom: Boolean)

    /**
     * 返回高亮绘制内容的半径
     */
    abstract fun getRadius(data: PieEntity): Float

    /**
     * 获取X轴，Y轴偏移值
     * @return 第一个参数为X轴偏移距离，第二个参数为Y轴偏移距离
     */
    abstract fun getOffset(data: PieEntity): Pair<Float, Float>
}


